package com.imooc.service.impl;

import com.imooc.es.pojo.Items;
import com.imooc.es.pojo.Stu;
import com.imooc.service.ItemsESService;
import com.imooc.utils.PagedGridResult;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ItemsESServiceImpl implements ItemsESService {

    @Autowired
    private ElasticsearchTemplate esTemplate;

    @Override
    public PagedGridResult searhItems(String keywords,
                                       String sort,
                                       Integer page,
                                       Integer pageSize) {

        Pageable pageable = PageRequest.of(page,pageSize);

        /**
         * 由前端来进行高亮样式的自定义，后端这边返回一个默认的em标签即可
         */
        /*String preTag = "<font color='red'>";
        String postTag = "</font>";*/

        String itemNameFiled = "itemName";

        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery(itemNameFiled,keywords)) // 构建查询条件
                .withPageable(pageable) // 构建分页条件
                .withHighlightFields(new HighlightBuilder.Field(itemNameFiled)
//                        .preTags(preTag)
//                        .postTags(postTag)
                ) // 构建高亮条件
                .build();
        AggregatedPage<Items> pageItems = esTemplate.queryForPage(query, Items.class, new SearchResultMapper() {
            // 对查询出来的结果做一个映射，自定义映射
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                List<Items> itemsListHighlt = new ArrayList<>();
                SearchHits searchHits = response.getHits();
                for(SearchHit h : searchHits){
                    Items item = mapSearchHit(h,Items.class);
                    itemsListHighlt.add(item);
                }

                // 放入数据和分页数据以及总的命中数
                return new AggregatedPageImpl<>((List<T>)itemsListHighlt,
                                                pageable,
                                                response.getHits().getTotalHits());

            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
                HighlightField hlField = searchHit.getHighlightFields().get(itemNameFiled);
                String itemName = hlField.getFragments()[0].toString();
                Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
                String itemId = (String)sourceAsMap.get("itemId");
                String imgUrl = (String)sourceAsMap.get("imgUrl");
                Integer price = (Integer) sourceAsMap.get("price");
                Integer sellCounts = (Integer) sourceAsMap.get("sellCounts");

                Items item = new Items();
                item.setItemId(itemId);
                item.setImgUrl(imgUrl);
                item.setItemName(itemName);
                item.setPrice(price);
                item.setSellCounts(sellCounts);
                return (T)item;
            }
        });
        System.out.println("检索后的总分页数目为："+pageItems.getTotalPages());
        // 文档数据
        List<Items> itemsList = pageItems.getContent();

        PagedGridResult result = new PagedGridResult();
        result.setRows(itemsList);
        result.setPage(page+1);
        result.setTotal(pageItems.getTotalPages());
        // 总记录数
        result.setRecords(pageItems.getTotalElements());

        return result;
    }
}
